﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using CultuRAM.Models;
using CultuRAM.DAL;
using PagedList;

namespace CultuRAM.Controllers
{
    [Authorize]
    public class EventParticipantController : Controller
    {
        private readonly UnitOfWork _unitOfWork = EventController._unitOfWork;
        private readonly CacheMode _cacheMode = EventController._CacheMode;

        //
        // GET: /EventParticipant/Default

        public ActionResult Default()
        {
            return PartialView("_Default");
        }

        // 
        // GET: /EventParticipant/

        public ActionResult IndexPv(int page, int idEvent)
        {
            var lista = GetParticipantsByEventIdPaged(idEvent, _cacheMode.Active, page);

            ViewBag.idEv = idEvent;

            return PartialView("_Index", lista);
        }

        // 
        // GET: /EventParticipant/Create

        public ActionResult CreatePv(int idEvent = 0)
        {
            try
            {
                EventParticipant lastOrDefault;

                if (!_cacheMode.Active)
                {
                    lastOrDefault = _unitOfWork.EventParticipantRepository.Get().LastOrDefault();
                }
                else
                {
                    lastOrDefault = _cacheMode.ParticipantsList.Any() ? 
                        _cacheMode.ParticipantsList.ToList().LastOrDefault() :
                        _unitOfWork.EventParticipantRepository.Get().LastOrDefault();
                }

                var lastIdPar = lastOrDefault != null ? lastOrDefault.EventParticipantId + 1 : 1;

                var par = new EventParticipant()
                    {
                        EventParticipantId = lastIdPar, EventId = idEvent
                    };

                ViewBag.Participants = PopulateParticipantsDropDownList();

                return PartialView("Create", par);
            }
            catch (Exception)
            {
                ViewBag.MsgError = new MvcHtmlString("Ocorreu um erro ao tentar adicionar o Artista!");
                return PartialView("_Default");
            }
        }

        // 
        // POST: /EventParticipant/Create

        [HttpPost]
        public ActionResult CreatePv(EventParticipant participant)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    if (_cacheMode.Active)
                    {
                        if (_cacheMode.ParticipantsList.Any(
                            item => item.ParticipantId == participant.ParticipantId && item.EventId == participant.EventId))
                        {
                            ViewBag.MsgError = "O Artista escolhido já existe!";
                            return PartialView("_Default");
                        }

                        participant.Event = _cacheMode.EventsList.ToList().FirstOrDefault(ev => ev.EventId == participant.EventId);
                        participant.Participant = _unitOfWork.ParticipantRepository.GetByID(participant.ParticipantId);
                        _cacheMode.ParticipantsList.Add(participant);
                    }
                    else
                    {
                        if (_unitOfWork.EventParticipantRepository.Get().Any(
                                    item => item.ParticipantId == participant.ParticipantId && item.EventId == participant.EventId))
                        {
                            ViewBag.MsgError = "O Artista escolhido já existe!";
                            return PartialView("_Default");
                        }

                        participant.Event = _unitOfWork.EventRepository.GetByID(participant.EventId);
                        _unitOfWork.EventParticipantRepository.Insert(participant);
                        _unitOfWork.Save();
                    }

                    ViewBag.MsgSuccess = "O Artista foi registado com Sucesso!";
                    return PartialView("_Default");
                }
                catch (Exception ex)
                {
                    var error = ex;
                    ViewBag.MsgError = "Ocorreu um erro ao tentar adicionar o Artista!";
                    return PartialView("_Default");
                }
            }

            ViewBag.Participants = PopulateParticipantsDropDownList(participant.ParticipantId);

            return PartialView("Create", participant);                  
        }

        // 
        // GET: /EventParticipant/Edit/5

        public PartialViewResult EditPv(int id = 0)
        {
            try
            {
                if (id == 0)
                {
                    ViewBag.MsgWarning = new MvcHtmlString("<b>ATENÇÃO:</b><br> Selecione o artista que pretende editar, clicando numa das linhas da tabela!");
                    return PartialView("_Default");
                }

                EventParticipant participant = null;

                if (_cacheMode.Active)
                {
                    foreach (var item in _cacheMode.ParticipantsList.Where(item => item.EventParticipantId == id))
                    {
                        participant = item;
                        break;
                    }
                }
                else
                {
                    participant = _unitOfWork.EventParticipantRepository.GetByID(id);
                }


                if (participant == null)
                {
                    ViewBag.MsgError = "Ocorreu um erro ao tentar editar o Artista. Certifique-se que selecionou um Artísta!";
                    return PartialView("_Default");
                }

                var evId = participant.EventId == 0 ? participant.Event.EventId : participant.EventId;

                ViewBag.Participants = PopulateParticipantsDropDownList(participant.ParticipantId);
                ViewBag.Events = PopulateEventDropDownList(participant.EventId);

                return PartialView("Edit", participant);
            }
            catch (Exception)
            {
                ViewBag.MsgError = "Ocorreu um erro ao tentar editar o Artista!";
                return PartialView("_Default");
            }
        }

        // 
        // POST: /EventParticipant/Edit/5

        [HttpPost]
        public PartialViewResult EditPv(EventParticipant participant)
        {
            try
            {
                var evId = participant.EventId == 0 ? participant.Event.EventId : participant.EventId;

                var ev = new Event();
                var listPar = new List<EventParticipant>();

                if (_cacheMode.Active)
                {

                    foreach (var item in _cacheMode.EventsList.Where(item => item.EventId == evId))
                    {
                        participant.Event = item;
                        participant.Participant = _unitOfWork.ParticipantRepository.GetByID(participant.ParticipantId);
                        ev = item;
                    }

                    listPar.AddRange(_cacheMode.ParticipantsList.Where(item => item.EventId == evId));
                    ev.EventParticipants = listPar.ToList();
                }
                else
                {
                    foreach (var item in _unitOfWork.EventRepository.Get().Where(item => item.EventId == evId))
                    {
                        participant.Event = item;
                        participant.Participant = _unitOfWork.ParticipantRepository.GetByID(participant.ParticipantId);
                        ev = item;
                    }

                    ev.EventParticipants = GetParticipantsByEventId(evId, _cacheMode.Active);
                }

                participant.EventId = evId;

                if (ModelState.IsValid)
                {
                    if (_cacheMode.Active)
                    {
                        foreach (var item in _cacheMode.ParticipantsList.Where(item => item.EventParticipantId == participant.EventParticipantId))
                        {
                            _cacheMode.ParticipantsList.Remove(item);
                            _cacheMode.ParticipantsList.Add(participant);
                            break;
                        }
                    }
                    else
                    {
                        _unitOfWork.EventParticipantRepository.Update(participant);
                        _unitOfWork.Save();
                    }

                    ViewBag.MsgSuccess = "O Artísta foi alterado com sucesso!";
                    return PartialView("_Default");
                }

                ViewBag.Participants = PopulateParticipantsDropDownList(participant.ParticipantId);
                ViewBag.Events = PopulateEventDropDownList(participant.EventId);

                return PartialView("Edit", participant);

            }
            catch (Exception)
            {
                ViewBag.MsgError = "Ocorreu um erro ao tentar editar o Artista!";
                return PartialView("_Default");
            }
        }

        // 
        // GET: /EventParticipant/Delete/5

        public PartialViewResult DeletePv(int id = 0)
        {
            try
            {
                if (id == 0)
                {
                    ViewBag.MsgWarning = new MvcHtmlString("<b>ATENÇÃO:</b><br> Selecione o artista que pretende editar, clicando numa das linhas da tabela!");
                    return PartialView("_Default");
                }

                EventParticipant participant = null;

                if (_cacheMode.Active)
                {
                    foreach (var item in _cacheMode.ParticipantsList.Where(item => item.EventParticipantId == id))
                    {
                        participant = item;
                        break;
                    }
                }
                else
                {
                    participant = _unitOfWork.EventParticipantRepository.GetByID(id);
                }

                if (participant == null)
                {
                    ViewBag.MsgError = "Ocorreu um erro ao tentar eliminar o Artísta. Certifique-se que selecionou um Artísta!";
                    return PartialView("_Default");
                }

                var evId = participant.EventId == 0 ? participant.Event.EventId : participant.EventId;

                ViewBag.Participants = PopulateParticipantsDropDownList(participant.ParticipantId);
                ViewBag.Events = PopulateEventDropDownList(participant.EventId);

                return PartialView("Delete", participant);
            }
            catch (Exception)
            {
                ViewBag.MsgError = "Ocorreu um erro ao tentar eliminar o Artísta!";
                return PartialView("_Default");
            }
        }

        // 
        // POST: /EventParticipant/Delete/5

        [HttpPost, ActionName("DeletePv")]
        public PartialViewResult DeleteConfirmedPv(EventParticipant participant)
        {
            var evId = participant.EventId == 0 ? participant.Event.EventId : participant.EventId;

            if (_cacheMode.Active)
            {

                foreach (var item in _cacheMode.EventsList.Where(item => item.EventId == evId))
                {
                    participant.Event = item;
                }
            }

            participant.EventId = evId;

            if (ModelState.IsValid)
            {
                if (_cacheMode.Active)
                {
                    foreach (var item in _cacheMode.ParticipantsList.Where(item => item.EventParticipantId == participant.EventParticipantId))
                    {
                        _cacheMode.ParticipantsList.Remove(item);
                        break;
                    }
                }
                else
                {
                    _unitOfWork.EventParticipantRepository.Delete(participant.EventParticipantId);
                    _unitOfWork.Save(); 
                }

                ViewBag.MsgSuccess = "O Artísta foi eliminado com sucesso!";
                return PartialView("_Default");
            }

            ViewBag.Participants = PopulateParticipantsDropDownList(participant.ParticipantId);
            ViewBag.Events = PopulateEventDropDownList(participant.EventId);

            return PartialView("Delete", participant);
        }



        //AUXILIARY METHODS /////////////////////////////////////////////////////////

        #region Auxiliary_Methods

        //Method: Get the list of all Participants by ID - Paged
        public IPagedList<EventParticipant> GetParticipantsByEventIdPaged(int eventId, bool activeCache, int page = 1)
        {
            return activeCache ? _cacheMode.ParticipantsList.Where(x => x.EventId == eventId).ToPagedList(page, 7)
                : _unitOfWork.EventParticipantRepository.Get(filter: x => x.EventId == eventId).OrderBy(o => o.Participant.Name).ToPagedList(page, 7);
        }

        //Method: Get the list of all Participants by ID
        public IList<EventParticipant> GetParticipantsByEventId(int eventId, bool activeCache, int page = 1)
        {
            return activeCache ? _cacheMode.ParticipantsList.Where(x => x.EventId == eventId).ToList()
                : _unitOfWork.EventParticipantRepository.Get(filter: x => x.EventId == eventId).OrderBy(o => o.Participant.Name).ToList();
        }

        //Method: Populate the DropDownList of Participants
        private SelectList PopulateParticipantsDropDownList(int? selectedParticipId = 0)
        {
            var parts = _unitOfWork.ParticipantRepository.GetList().OrderBy(o => o.Name);
            return selectedParticipId != 0 ?
                new SelectList(parts, "ParticipId", "Name") :
                new SelectList(parts, "ParticipId", "Name", selectedParticipId);
        }

        //Method: Populate the DropDownList of Events
        private SelectList PopulateEventDropDownList(int? selectedEventId = 0)
        {
            var events = _unitOfWork.EventRepository.GetList();

            return selectedEventId == 0 ?
                 new SelectList(events, "EventId", "Title") :
                 new SelectList(events, "EventId", "Title", selectedEventId);
        }

        #endregion


    } //Class CommentController

} //Namespace CultuRAM.Controllers


